//
//  LDXNetwork.swift
//  RequestLib
//
//  Created by 刘东旭 on 2022/1/3.
//  Copyright © 2022 刘东旭. All rights reserved.
//

import Foundation

protocol LDXRequestable {
    func request() -> URLRequest?
}

protocol LDXConvertible {
    init(_ data: Data?)
}

struct LDXRequest: LDXRequestable {
    var urlString: String

    var method: HTTPMethod
    var parameters: [String: Any]?
    var headers: [String: Any]?
    
    func request() -> URLRequest? {
        var param = ""
        if method == .GET {
            if parameters?.count ?? 0 > 0 {
                param.append("?")
            }
            parameters?.forEach { (key, value) in
                param.append(key)
                param.append("=")
                param.append("\(value)")
            }
        }
        guard let url = URL(string: urlString + param) else { return nil }
        var request = URLRequest(url: url)
        request.httpMethod = method.rawValue
        if method == .POST {
            if parameters != nil {
                request.httpBody = try? JSONSerialization.data(withJSONObject: parameters!, options: [])
            }
        }
        headers?.forEach { (key, value) in
            request.addValue("\(value)", forHTTPHeaderField: key)
        }
        return request
    }
}

//enum HTTPMethod: String {
//    case GET
//    case POST
//}

struct LDXNetwork {
    struct LDXError: Error {
        var desc: String = ""
        var localizedDescription: String {
            return desc
        }
        init(_ desc: String) {
            self.desc = desc
        }
    }
    static func request<T: LDXRequestable, S: LDXConvertible>(request: T, resultType: S.Type, completionHandler: @escaping (_ ret: S?, _ response: URLResponse?, _ error: Error?) -> Void) {
        guard let req = request.request() else {
            completionHandler(nil, nil, LDXError("request is nil"))
            return
        }
        let task = URLSession.shared.dataTask(with: req, completionHandler: { data, resp, error in
            completionHandler(resultType.init(data),resp,error)
        })
        task.resume()
    }
}
